2. Grilla de estimación
Nuestro objetivo es determinar el volumen espacial que sera el limite de nuestro modelo de recursos. Es decir, no estimaremos mas allá de los limites representados por esta caja.
Nuestro punto de partida sera la base de datos compositada a 6 metros, en donde los valores -99 han sido ya filtrados.
2.1. Simplificacion de base de datos compositada
[12]:
## Cargar datos ya compositados y con UGs del capitulo anterior
import pandas as pd
import numpy as np
# Cargar base de datos en pandas
df_original = pd.read_csv('Data_compositada_con_UGs.csv', sep=',', encoding='latin1')
df_original
[12]:
| cu_pct | UG | dhid | from | to | SURV_X | SURV_Y | SURV_Z | |
|---|---|---|---|---|---|---|---|---|
| 0 | 0.020300 | 2.0 | 98CCD089 | 12.2 | 18.2 | 472187.343570 | 6.925806e+06 | 4211.772172 |
| 1 | 0.009500 | 2.0 | 98CCD089 | 18.2 | 24.2 | 472187.740701 | 6.925807e+06 | 4205.844155 |
| 2 | 0.006767 | 2.0 | 98CCD089 | 24.2 | 30.2 | 472188.089349 | 6.925807e+06 | 4199.915106 |
| 3 | 0.010433 | 2.0 | 98CCD089 | 30.2 | 36.2 | 472188.470072 | 6.925808e+06 | 4193.995578 |
| 4 | 0.011133 | 2.0 | 98CCD089 | 36.2 | 42.2 | 472188.878860 | 6.925809e+06 | 4188.084383 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 16877 | 0.095000 | 4.0 | CCDDH-007 | 450.0 | 456.0 | 471922.691912 | 6.925392e+06 | 4022.517796 |
| 16878 | 0.109000 | 4.0 | CCDDH-007 | 456.0 | 462.0 | 471924.631624 | 6.925395e+06 | 4017.651413 |
| 16879 | 0.179667 | 4.0 | CCDDH-007 | 462.0 | 468.0 | 471926.586648 | 6.925397e+06 | 4012.784519 |
| 16880 | 0.148333 | 4.0 | CCDDH-007 | 468.0 | 474.0 | 471928.548677 | 6.925400e+06 | 4007.918137 |
| 16881 | 0.206000 | 4.0 | CCDDH-007 | 474.0 | 480.0 | 471930.530423 | 6.925403e+06 | 4003.054819 |
16882 rows × 8 columns
Limpiaremos la base de datos para simplificar la notación, asi como para mantener solo las columnas correspondiente a las coordenadas, variable de interés y Unidades Geológicas.
[13]:
# Limpiar la base de datos: mantener solo las columnas especificadas y renombrar
df = df_original[['SURV_X', 'SURV_Y', 'SURV_Z', 'cu_pct', 'UG']].copy()
# Renombrar las columnas de coordenadas
df = df.rename(columns={
'SURV_X': 'X',
'SURV_Y': 'Y',
'SURV_Z': 'Z'
})
# exportamos base de datos limpia
df.to_csv('data.csv', index=False)
df
[13]:
| X | Y | Z | cu_pct | UG | |
|---|---|---|---|---|---|
| 0 | 472187.343570 | 6.925806e+06 | 4211.772172 | 0.020300 | 2.0 |
| 1 | 472187.740701 | 6.925807e+06 | 4205.844155 | 0.009500 | 2.0 |
| 2 | 472188.089349 | 6.925807e+06 | 4199.915106 | 0.006767 | 2.0 |
| 3 | 472188.470072 | 6.925808e+06 | 4193.995578 | 0.010433 | 2.0 |
| 4 | 472188.878860 | 6.925809e+06 | 4188.084383 | 0.011133 | 2.0 |
| ... | ... | ... | ... | ... | ... |
| 16877 | 471922.691912 | 6.925392e+06 | 4022.517796 | 0.095000 | 4.0 |
| 16878 | 471924.631624 | 6.925395e+06 | 4017.651413 | 0.109000 | 4.0 |
| 16879 | 471926.586648 | 6.925397e+06 | 4012.784519 | 0.179667 | 4.0 |
| 16880 | 471928.548677 | 6.925400e+06 | 4007.918137 | 0.148333 | 4.0 |
| 16881 | 471930.530423 | 6.925403e+06 | 4003.054819 | 0.206000 | 4.0 |
16882 rows × 5 columns
2.2. Determinación de parámetros de la grilla
Para lo que sigue, sera necesario saber con exactitud los limites de nuestro modelo de bloques, dado un tamaño de bloque fijo. Para esto, definimos que el tamaño de cada de bloque sera de 15 metros x 15 metros x 15 metros (largo x ancho x alto o bien incremento en el eje X, incremento en el eje Y e incremento en el eje Z).
Los limites preliminares los podemos encontrar inspeccionando nuestros datos, buscando aquel más alto, aquel más bajo, el más al oeste y el más al este, e igualmente en la norte-sur.
[14]:
xmin = df['X'].min()
xmax = df['X'].max()
ymin = df['Y'].min()
ymax = df['Y'].max()
zmin = df['Z'].min()
zmax = df['Z'].max()
print(f"Xmin: {xmin:.2f}, Xmax: {xmax:.2f}")
print(f"Ymin: {ymin:.2f}, Ymax: {ymax:.2f}")
print(f"Zmin: {zmin:.2f}, Zmax: {zmax:.2f}")
Xmin: 471116.24, Xmax: 473023.89
Ymin: 6924721.57, Ymax: 6926164.63
Zmin: 2950.02, Zmax: 4445.78
En base a estos limites y el tamaño definido para cada bloque, podemos encontrar el numero de bloques en cada dirección y el tamaño total de nuestra grilla.
[15]:
block_size_x = 15 # Tamaño del bloque en X (metros)
block_size_y = 15 # Tamaño del bloque en Y (metros)
block_size_z = 15 # Tamaño del bloque en Z (metros)
Nx = int((xmax - xmin) / block_size_x) + 1
Ny = int((ymax - ymin) / block_size_y) + 1
Nz = int((zmax - zmin) / block_size_z) + 1
print(f"Número de bloques en X: {Nx}")
print(f"Número de bloques en Y: {Ny}")
print(f"Número de bloques en Z: {Nz}")
grid_size_x = Nx * block_size_x
grid_size_y = Ny * block_size_y
grid_size_z = Nz * block_size_z
print(f"Tamaño total de la grilla en X: {grid_size_x} metros")
print(f"Tamaño total de la grilla en Y: {grid_size_y} metros")
print(f"Tamaño total de la grilla en Z: {grid_size_z} metros")
print(f"Dimensiones de la grilla de estimación: {Nx} x {Ny} x {Nz} bloques")
print(f"Tamaño total de la grilla: Nx*Ny*Nz = {Nx * Ny * Nz} bloques")
Número de bloques en X: 128
Número de bloques en Y: 97
Número de bloques en Z: 100
Tamaño total de la grilla en X: 1920 metros
Tamaño total de la grilla en Y: 1455 metros
Tamaño total de la grilla en Z: 1500 metros
Dimensiones de la grilla de estimación: 128 x 97 x 100 bloques
Tamaño total de la grilla: Nx*Ny*Nz = 1241600 bloques
Nota: Anotamos estos parámetros ya que recurrimos a estos números constantemente en los flujos de trabajo posteriores
[16]:
# imprimir parámetros en formato GSLIB
# 50 0.5 1.0 -nx,xmn,xsiz
# 50 0.5 1.0 -ny,ymn,ysiz
# 1 0.5 1.0 -nz,zmn,zsiz
print(f"{Nx} {xmin:.2f} {block_size_x:.0f}\t\t\t-nx,xmn,xsiz")
print(f"{Ny} {ymin:.2f} {block_size_y:.0f}\t\t\t-ny,ymn,ysiz")
print(f"{Nz} {zmin:.2f} {block_size_z:.0f}\t\t\t-nz,zmn,zsiz")
128 471116.24 15 -nx,xmn,xsiz
97 6924721.57 15 -ny,ymn,ysiz
100 2950.02 15 -nz,zmn,zsiz
Como hemos calculado, nuestro modelo tendrá un total de 1.241.600 de bloques, lo que corresponde a un modelo dentro del estándar de la industria, considerando los números que se manejan allí. Este numero de información, sin embargo, no puede ser manejado por la mayoría de los softwares de oficina como Excel, por lo que tendremos que recurrir a otro tipo de herramientas para el manejo de estos datos.
2.3. Visualizacion de los limites de la grilla
Procedemos a visualizar los limites de nuestro modelo de bloques junto con las muestras para verificación.
[33]:
continuous = 'cu_pct'
import plotly.io as pio
# pio.renderers.default = "colab"
pio.renderers.default = "notebook" # usar esta linea en jupyter notebook o vscode
import plotly.graph_objects as go
import plotly.express as px
import plotly.offline as py
fig = go.Figure(data=[go.Scatter3d(
x=df['X'],
y=df['Y'],
z=df['Z'],
marker=dict(color=df[continuous],
colorscale=px.colors.sequential.Rainbow[1:],
cmin=0.0,
cmax=df[continuous].quantile(0.95),
size=2.0, # Esta opcion controla el tamaño de los datos
colorbar=dict(
title='Cu [%]',
thickness=20,
# Add a border to the colorbar
outlinecolor='black', # Color of the border
outlinewidth=2, # Width of the border
bordercolor='white', # Background border color (if applicable)
borderwidth=1 # Background border width
)
),
mode='markers',
opacity=1
)])
# otras opciones para controlar el color de los elementos de la figura, borrar hovermode para desactivar etiquetas al pasar el mouse
fig.update_layout(scene = dict(
xaxis = dict(
title='Este',
backgroundcolor="white",
gridcolor="gray",
showbackground=True,
zerolinecolor="white",),
yaxis = dict(
title='Norte',
backgroundcolor="white",
gridcolor="gray",
showbackground=True,
zerolinecolor="white"),
zaxis = dict(
title='Elevación',
backgroundcolor="white",
gridcolor="gray",
showbackground=True,
zerolinecolor="white",),
),
font_family="Times New Roman",
font_color="black", hovermode=False
)
# Definir los vértices del cubo
cube_x = [xmin, xmax, xmax, xmin, xmin, xmax, xmax, xmin]
cube_y = [ymin, ymin, ymax, ymax, ymin, ymin, ymax, ymax]
cube_z = [zmin, zmin, zmin, zmin, zmax, zmax, zmax, zmax]
# Añadir aristas (wireframe) para mejor visualización
edge_pairs = [(0,1),(1,2),(2,3),(3,0),(4,5),(5,6),(6,7),(7,4),(0,4),(1,5),(2,6),(3,7)]
edge_x, edge_y, edge_z = [], [], []
for a, b in edge_pairs:
edge_x += [cube_x[a], cube_x[b], None]
edge_y += [cube_y[a], cube_y[b], None]
edge_z += [cube_z[a], cube_z[b], None]
# Añadir las aristas a la figura sin leyenda ni colorbar ni hoverinfo ni otros elementos
fig.add_trace(go.Scatter3d(
x=edge_x,
y=edge_y,
z=edge_z,
mode='lines',
line=dict(color='black', width=2),
showlegend=False,
hoverinfo='skip'
))
# ocultar la leyenda/autonombre "trace 0" junto al colorbar
fig.update_layout(showlegend=False)
fig.show()